﻿using System;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents; //consider removing
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.Generic;


namespace mates_viz
{

	public class locationKey
	{
		Grid mylocGrid;
		ScrollViewer scroller;
		Style mybuttonStyle;
		int numLocs;
		public delegate void locKey_Hover_Delegate(int loc_id, Color loc_color, string loc_name);
		public event locKey_Hover_Delegate locKey_Hover_Event;

		private struct locTag
		{
			public locTag(int Loc_Id, int Row, int Col, Color Loc_Color, string Loc_Name)
			{
				loc_id = Loc_Id;
				row = Row;
				col = Col;
				loc_color = Loc_Color;
				loc_name = Loc_Name;
			}
			public int loc_id;
			public int row;
			public int col;
			public Color loc_color;
			public string loc_name;
		}


		public locationKey(Style buttonStyle)
		{
			mybuttonStyle = buttonStyle;
			numLocs = 0;
			mylocGrid = new Grid();
			scroller = new ScrollViewer();
			scroller.VerticalScrollBarVisibility = ScrollBarVisibility.Hidden;
			scroller.HorizontalScrollBarVisibility = ScrollBarVisibility.Auto;
			scroller.Content = mylocGrid;
			
			mylocGrid.RowDefinitions.Add(new RowDefinition());
			mylocGrid.RowDefinitions.Add(new RowDefinition());

			ColumnDefinition newCol = new ColumnDefinition();
			newCol.Width = new GridLength(1, GridUnitType.Star);
			mylocGrid.ColumnDefinitions.Add(newCol);

			newCol = new ColumnDefinition();
			newCol.Width = new GridLength(1, GridUnitType.Star);
			mylocGrid.ColumnDefinitions.Add(newCol);
		}
		public ScrollViewer locScrollViewer
		{
			get { return scroller; }
		}
		public void addLoc(int loc_id, string locName, Color bgcolor)
		{
			int row = numLocs % 2;
			int col = numLocs / 2 + 1;
			if (row == 0) // new row -> new col
			{
				ColumnDefinition newCol = new ColumnDefinition();
				newCol.Width = new GridLength(1, GridUnitType.Auto);
				mylocGrid.ColumnDefinitions.Insert(col, newCol);
			}
			++numLocs;

			Button newButton = new Button();
			newButton.Style = mybuttonStyle;
			newButton.Content = locName;

			newButton.Tag = new locTag(loc_id, row, col, bgcolor, locName);

			newButton.Background = new SolidColorBrush(bgcolor);
			newButton.HorizontalAlignment = HorizontalAlignment.Left;

			newButton.MouseEnter += new System.Windows.Input.MouseEventHandler(locKey_Hover);

			mylocGrid.Children.Add(newButton);
			Grid.SetColumn(newButton, col);
			Grid.SetRow(newButton, row);
		}

		void locKey_Hover(object sender, System.Windows.Input.MouseEventArgs e)
		{
			locKey_Hover_Event(((locTag)((Button)sender).Tag).loc_id, ((locTag)((Button)sender).Tag).loc_color, ((locTag)((Button)sender).Tag).loc_name);
		}

		public void removeLoc(int loc_id)
		{
			locTag removed_tag = new locTag();
			foreach (Button button in mylocGrid.Children)
			{
				if (((locTag)button.Tag).loc_id == loc_id)
				{
					removed_tag = (locTag)button.Tag;
					mylocGrid.Children.Remove(button);
					--numLocs;
					break;
				}
			}

			bool lastcol_empty = true;
			int numcols = numLocs / 2 + 1;
			foreach (Button button in mylocGrid.Children)
			{
				locTag buttonTag = (locTag)button.Tag;
				if (buttonTag.col * 2 + buttonTag.row > removed_tag.col * 2 + removed_tag.row) // if current > removed
				{
					if (buttonTag.row == 0)
					{
						Grid.SetColumn(button, buttonTag.col - 1);
						Grid.SetRow(button, 1);
						button.Tag = new locTag(buttonTag.loc_id, 1, buttonTag.col - 1, buttonTag.loc_color, buttonTag.loc_name);
					}
					else
					{
						Grid.SetRow(button, 0);
						button.Tag = new locTag(buttonTag.loc_id, 0, buttonTag.col, buttonTag.loc_color, buttonTag.loc_name);
						if (buttonTag.col == numcols)
							lastcol_empty = false;
					}
				}
			}
			if (lastcol_empty)
				mylocGrid.ColumnDefinitions.Remove(mylocGrid.ColumnDefinitions[numcols]);
		}
	}
	public class locationPanel
	{
		Grid locationPanelGrid;
		int loc_id; public int Loc_ID { get { return loc_id; } }

		public locationPanel(Grid locationPanelGrid_In) { locationPanelGrid = locationPanelGrid_In; }

		public void UpdateWall(string WallText, string LastUpdatedTs, string UpdatedBy)
		{
			// Make call to state manager, get locUsers, wallUpdated, wallContents
			// wall = wallContents;
			((TextBox)locationPanelGrid.FindId("locationPanel_wall")).Text = WallText;
			//((TextBlock)locationPanelGrid.FindId("locationPanel_locUsers_locDist_locDir")).TextContent = locUsers + " users, " + locDistance + "' " + locDirection;
			((TextBlock)locationPanelGrid.FindId("locationPanel_lastUpdated")).TextContent = LastUpdatedTs;
			((TextBlock)locationPanelGrid.FindId("locationPanel_updatedBy")).TextContent = UpdatedBy;
		}

		public void viewLoc(int locID, Color bgcolor, string locName, string distDir)
		{
			loc_id = locID;
			((Rectangle)locationPanelGrid.FindId("locationPanel_locRectangle")).Fill = new SolidColorBrush(bgcolor);
			((TextBlock)locationPanelGrid.FindId("locationPanel_locName")).TextContent = locName;
            ((TextBlock)locationPanelGrid.FindId("locationPanel_locUsers_locDist_locDir")).TextContent = distDir;
		}
	}
  
	public class FriendDisplay
	{
//		public delegate void UIUserClickDelegate(object IdentifierTag);
//		public event UIUserClickDelegate FriendRightClicked;



		public delegate void FriendEventDelegate(string friendName);
		public event FriendEventDelegate Friend_LeftClick_Event;
		public event FriendEventDelegate FriendRemove;
		

		StackPanel FriendPanel;
		public FriendDisplay(StackPanel Panel) { FriendPanel = Panel; }

		private class FriendButton
		{
			public Button myButton;
			public string name;

			public FriendButton(string Name, Style style_MenuItem, Style style_friendMenu)
			{
				name = Name;
				myButton = new Button();
				myButton.Tag = Name;
				myButton.Content = Name;

				ContextMenu cmenu = new ContextMenu();

				MenuItem mi = new MenuItem();
				mi.Header = "Remove " + Name;
				mi.Tag = Name;
				mi.Style = style_MenuItem;
				cmenu.Items.Add(mi);

				cmenu.Style = style_friendMenu;

				myButton.ContextMenu = (cmenu);
			}

		}
		private List<FriendButton> ListOfFriendButtons = new List<FriendButton>();
		public void AddFriend(string FriendName)
		{
			if (ListOfFriendButtons.Count == 0)
				FriendPanel.Children[0].Visibility = Visibility.Collapsed;
			foreach (FriendButton button in ListOfFriendButtons)
				if (button.name == FriendName) return;
			FriendButton newButton = new FriendButton(FriendName, (Style)FriendPanel.FindResource("friendMenuItem"), (Style)FriendPanel.FindResource("friendMenu"));
			this.ListOfFriendButtons.Add(newButton);
			newButton.myButton.Style = (Style)FriendPanel.FindResource("glowButtonSquare");
			((MenuItem)newButton.myButton.ContextMenu.Items[0]).Click += new RoutedEventHandler(FriendRemove_Click);
			newButton.myButton.Click += new RoutedEventHandler(FriendDisplay_LeftClick);

            FriendPanel.Children.Insert(ListOfFriendButtons.Count - 1, newButton.myButton);
		}

		void FriendDisplay_LeftClick(object sender, RoutedEventArgs e)
		{
			Friend_LeftClick_Event((string)((Button)sender).Content);
		}

		void FriendRemove_Click(object sender, RoutedEventArgs e)
		{
			// send an event that the user asked to remove this friend
			FriendRemove((string)((MenuItem)sender).Tag);  
		}

		public void RemoveFriend(string FriendName)
		{
			foreach (FriendButton button in ListOfFriendButtons)
			{
				if (button.name == FriendName)
				{
					FriendPanel.Children.Remove(button.myButton);
					this.ListOfFriendButtons.Remove(button);
					return;
				}
			}
		}
	}
    public class LocGuessDisplay{
        public delegate void UILocationClickDelegate(object IdentifierTag);
        public event UILocationClickDelegate LocationSelected;
        StackPanel LocGuessPanel;
        public LocGuessDisplay(StackPanel Panel){LocGuessPanel = Panel;}
        private class LocGuessButton{
            public Button myButton;
            public string name;
            public double myScore;
            public LocGuessButton(object Tag, string Name, double Score){
                name = Name;
                myButton = new Button();
                string scoreStr = ((double)(Score * 100)).ToString("0");
                myButton.Content = Name + " (" + scoreStr + "%)";
                myButton.Tag = Tag;  // Pass the location ID as the tag
                myScore = Score;
            }

        }
        private List<LocGuessButton> ListOfLocGuessButtons = new List<LocGuessButton>();
        public void AddLocGuess(string Name, double Score, object IdentifierTag){
            LocGuessButton newButton = new LocGuessButton(IdentifierTag, Name, Score);
            this.ListOfLocGuessButtons.Add(newButton);
            newButton.myButton.Style = (Style)LocGuessPanel.FindResource("glowButton");
            // Set up an event handler for the newly created button
            newButton.myButton.Click += new RoutedEventHandler(locGuess_Click);
            LocGuessPanel.Children.Add(newButton.myButton);
        }
        void locGuess_Click(object sender, RoutedEventArgs e)
        {
            //try
            //{    
                object IdentifierTag = ((Button)sender).Tag;
                LocationSelected(IdentifierTag);
            //}
            //catch
            //{MessageBox.Show("Invalid location selected."); }
        }

    }
    public class LocGPSdisplay{
        public delegate void UILocationClickDelegate(object IdentifierTag);
        public event UILocationClickDelegate LocationSelected;
        StackPanel LocGPSPanel;
        public LocGPSdisplay(StackPanel Panel){LocGPSPanel = Panel;}
        private class LocGPSButton{
            public Button myButton;
            public string name;
            public string direction;
            public double distance;
            public LocGPSButton(string Name, double Distance, string Direction, object IdentifierTag){
                name = Name;
                myButton = new Button();
                myButton.Tag = IdentifierTag;
                myButton.Content = Name + string.Format(" 0 ft", distance) + " " + Direction;
                distance = Distance;
                direction = Direction;
            }
        }
        private List<LocGPSButton> ListOfLocGPSButtons = new List<LocGPSButton>();
        public void AddLocGPS(string Name, double Distance, string Direction, object IdentifierTag){
            LocGPSButton newButton = new LocGPSButton(Name, Distance, Direction, IdentifierTag);
            this.ListOfLocGPSButtons.Add(newButton);
            newButton.myButton.Style = (Style)LocGPSPanel.FindResource("glowButton");
            newButton.myButton.Click +=new RoutedEventHandler(locGPS_Click);
            LocGPSPanel.Children.Add(newButton.myButton);
        }
        void locGPS_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                object IdentifierTag = ((Button)sender).Tag;
                LocationSelected(IdentifierTag);
            }
            catch
            { MessageBox.Show("Invalid location selected."); }
        }
    }
    public class VizLocList
    {        
        ListBox locListBox;
        public VizLocList(ListBox Box) { locListBox = Box; }
        private class LocListItem
        {
            public Button myButton;
            public string name;
            public string direction;
            public double distance;
            public LocListItem(string Name, double Distance, string Direction, object IdentifierTag)
            {
                name = Name;
                myButton = new Button();
                myButton.Foreground = Brushes.White;
                myButton.Background = Brushes.Blue;
                myButton.Width = 200;
                myButton.Tag = IdentifierTag;
                if (Distance == 0)
                    myButton.Content = Name + " (here)" ;
                else
                    myButton.Content = Name + " " + Distance.ToString("0") + " ft " + Direction;

                distance = Distance;
                direction = Direction;
            }
        }
        private List<LocListItem> listOfLocItems = new List<LocListItem>();
        public void AddLocItem(string Name, double Distance, string Direction, Color locColor, object IdentifierTag)
        {
            LocListItem newButton = new LocListItem(Name, Distance, Direction, IdentifierTag);
            newButton.myButton.Background = new SolidColorBrush(locColor);  // color the loc properly
            listOfLocItems.Add(newButton);
            newButton.myButton.Style = (Style)locListBox.FindResource("locationButton");
            newButton.myButton.Click += new RoutedEventHandler(loc_Click);
            locListBox.Items.Add(newButton.myButton);
        }
        void loc_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                object IdentifierTag = ((Button)sender).Tag;
                //LocationSelected(IdentifierTag);
            }
            catch
            { MessageBox.Show("Invalid location selected."); }
        }
    }
    public partial class UI : Window
    {

        public enum state { login, guess, gps, running, register }

        
        private enum inputMode { addFriend, addInterest, addCourse }
        inputMode InputPanelMode;

        System.Timers.Timer refreshTimer;

        public delegate void DispatchDelegate();

        public delegate void UILoginClickDelegate(string user, string password);
        public event UILoginClickDelegate LoginClicked;

        public delegate void GPSLocSearchNearby(string gpsX, string gpsY); //Note: gpsX and gpsY SHOULD be doubles
        public event GPSLocSearchNearby gpsSearchNearby;

		//public delegate void LocationEvent(int loc_id);
		//public event LocationEvent LocationKeyHover;

        public delegate void UserRequest(string userString);
        public event UserRequest RemoveUserRequest;
        public event UserRequest AddFriendRequest;
		public event UserRequest RemoveFriendRequest;
        public event UserRequest AddInterestRequest;
		public event UserRequest RemoveInterestRequest;
		public event UserRequest AddCourseRequest;
        public event UserRequest RemoveCourseRequest;

        public event UserRequest InterestHoverOver;
        public event UserRequest InterestHoverOff;
        public event UserRequest CourseHoverOver;
        public event UserRequest CourseHoverOff;

        public event EventHandler AddNodeClicked;
        public event EventHandler RemoveNodeClicked;
        public event EventHandler RefreshClicked;

        
        public LocGuessDisplay locGuessDisplay;
        public LocGPSdisplay locGPSdisplay;
        public VizLocList vizLocList;                               // list of nearby locations
		public locationKey locKey;
		public FriendDisplay friendDisp;
		public locationPanel locPanel;
		bool friendsExpanded = true;    // is the friend panel expanded?
		bool profileExpanded = false;

        public UI() : base(){InitializeComponent();}
        private void WindowLoaded(object sender, EventArgs e) {
            friendDisp = new FriendDisplay(friendPanel);
//            classDisplay = new ClassDisplay(ClassPanel);
            locGuessDisplay = new LocGuessDisplay(LocGuessPanel);
            locGPSdisplay = new LocGPSdisplay(GPSLocPanel);

			// Build the initial location key
			locKey = new locationKey((Style)this.mainvizGrid.FindResource("locationButton"));
			mainvizGrid.Children.Add(locKey.locScrollViewer);
			Grid.SetColumn(locKey.locScrollViewer, 0);
			Grid.SetRow(locKey.locScrollViewer, 1);

			// Event Handlers for the location key
			friendDisp.Friend_LeftClick_Event += new FriendDisplay.FriendEventDelegate(Friend_LeftClick_Event);
			friendDisp.FriendRemove += new FriendDisplay.FriendEventDelegate(friendDisp_FriendRemove);

			// Build the initial location panel
			locPanel = new locationPanel(locationPanelGrid);

            refreshTimer = new System.Timers.Timer(4000);
            refreshTimer.Elapsed += new System.Timers.ElapsedEventHandler(refreshTimer_Elapsed);
            refreshTimer.Start();
		}

		// pass this event along
		void friendDisp_FriendRemove(string friendName)	{ RemoveFriendRequest(friendName);	}

		public void MoveUserInfoBox(Point to)
		{
			Canvas.SetLeft(userInfoGrid, to.X);
			Canvas.SetTop(userInfoGrid, to.Y);
		}

		public void addInterest(string interestName)
		{
			Label lbl = new Label();
			lbl.Content = interestName;
			lbl.Style = (Style)this.mainvizGrid.FindResource("interestLabel");
            lbl.MouseEnter += new System.Windows.Input.MouseEventHandler(interestLbl_MouseEnter);
            lbl.MouseLeave += new System.Windows.Input.MouseEventHandler(interestLbl_MouseLeave);

			ContextMenu cmenu = new ContextMenu();

			MenuItem mi = new MenuItem();
			mi.Header = "Remove " + interestName;
			mi.Tag = (object)interestName;
			mi.Style = (Style)this.mainvizGrid.FindResource("interestMenuItem");
			cmenu.Style = (Style)this.mainvizGrid.FindResource("interestMenu");
			mi.Click += new RoutedEventHandler(InterestRemove_Click);
			cmenu.Items.Add(mi);

			lbl.ContextMenu = (cmenu);

			TextFlow_Interests.ContentEnd.InsertEmbeddedElement(lbl);
        }

        void interestLbl_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
        {
            // highlight other users with this same common interest
            string interestName = ((Label)sender).Content.ToString();
            InterestHoverOff(interestName);
        }

        void interestLbl_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
        {
            // highlight other users with this same common interest
            string interestName = ((Label)sender).Content.ToString();
            InterestHoverOver(interestName);
        }

        void courseLbl_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
        {
            // highlight other users with this same common course
            string courseName = ((Label)sender).Content.ToString();
            CourseHoverOver(courseName);
        }

        void courseLbl_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
        {
            // highlight other users with this same common interest
            string courseName = ((Label)sender).Content.ToString();
            CourseHoverOff(courseName);
        }

        public void addCourse(string courseName)
        {
            Label lbl = new Label();
            lbl.Content = courseName;
            lbl.Style = (Style)this.mainvizGrid.FindResource("courseLabel");
            lbl.MouseEnter += new System.Windows.Input.MouseEventHandler(courseLbl_MouseEnter);
            lbl.MouseLeave += new System.Windows.Input.MouseEventHandler(courseLbl_MouseLeave);

            ContextMenu cmenu = new ContextMenu();

            MenuItem mi = new MenuItem();
            mi.Header = "Remove " + courseName;
            mi.Tag = (object)courseName;
            mi.Style = (Style)this.mainvizGrid.FindResource("courseMenuItem");
            cmenu.Style = (Style)this.mainvizGrid.FindResource("courseMenu");
            mi.Click += new RoutedEventHandler(CourseRemove_Click);
            cmenu.Items.Add(mi);

            lbl.ContextMenu = (cmenu);

            TextFlow_Courses.ContentEnd.InsertEmbeddedElement(lbl);
        }
        
        public void newMessage(string time, string from, string msg, bool outgoing)
		{
			// This is C# for:

			// <Grid Margin="2 2 2 0">
			// <ColumnDefinition Width="90"/>
			// <ColumnDefinition Width="90"/>
			// <ColumnDefinition Width="*"/>
			// <TextBlock Grid.Column="0" Style="{messageText}">[3:29pm]</TextBlock>
			// <TextBlock Grid.Column="1" HorizontalAlignment="Center" Foreground="#cccccc" FontFamily="Arial" FontSize="12">Ayush</TextBlock>
			// <TextBlock Grid.Column="2" Foreground="#cccccc" FontFamily="Arial" FontSize="12">I need to go to my interview now.</TextBlock>
			// </Grid>

			Grid grid = new Grid();
			grid.Margin = new Thickness(2, 2, 2, 0);

			Style messageText;
			if (outgoing == true)
			{
				messageText = (Style)this.mainvizGrid.FindResource("messageText_Outgoing");
			}
			else
			{
				messageText = (Style)this.mainvizGrid.FindResource("messageText");
			}

			ColumnDefinition col1 = new ColumnDefinition();
			col1.Width = new GridLength(90);
			grid.ColumnDefinitions.Add(col1);

			ColumnDefinition col2 = new ColumnDefinition();
			col2.Width = new GridLength(90);
			grid.ColumnDefinitions.Add(col2);

			ColumnDefinition col3 = new ColumnDefinition();
			col3.Width = new GridLength(1, GridUnitType.Star);
			grid.ColumnDefinitions.Add(col3);

			TextBlock msgTime = new TextBlock();
			msgTime.Style = messageText;
			msgTime.HorizontalAlignment = HorizontalAlignment.Center;
			msgTime.ContentEnd.InsertText(time);
			grid.Children.Add(msgTime);
			Grid.SetColumn(msgTime, 0);

			TextBlock msgFrom = new TextBlock();
			msgFrom.Style = messageText;
			msgFrom.HorizontalAlignment = HorizontalAlignment.Center;
			msgFrom.ContentEnd.InsertText(from);
			grid.Children.Add(msgFrom);
			Grid.SetColumn(msgFrom, 1);

			TextBlock Msg = new TextBlock();
            Msg.TextWrap = TextWrap.Wrap;
			Msg.Style = messageText;
			Msg.HorizontalAlignment = HorizontalAlignment.Left;
			Msg.ContentEnd.InsertText(msg);
			grid.Children.Add(Msg);
			Grid.SetColumn(Msg, 2);

            MessageWindow.Children.Add(grid);

            // GRR!!  These aren't working!!
            MessageWindowScroller.ScrollToBottom();
            MessageWindowScroller.ScrollToEnd();

		}

		private void AddFriendClicked(object sender, RoutedEventArgs args)
		{
			AddFriendRequest(friendNameTxtBox.Text);
			friendNameTxtBox.SelectAll();
			friendNameTxtBox.Focus();
		}


		public void PopulateUserInfoPanel(string UserName, string LocName, ref List<string> Relations)
		{

			infoCanvNameLabel.Content = UserName;
			infoCanvLocLabel.Content = LocName;

			// First, remove all existing relationships
			infoCanvRelationPanel.Children.Clear();

			foreach (string relnString in Relations)
			{
				System.Windows.Controls.Primitives.BulletPanel newBullet
					= new System.Windows.Controls.Primitives.BulletPanel();
				newBullet.Margin = new Thickness(5, 0, 5, 0);
				Rectangle bulletRect = new Rectangle();
				bulletRect.Width = 6; bulletRect.Height = 6;
				bulletRect.Fill = Brushes.White;
				TextBlock bulletText = new TextBlock();
				bulletText.Margin = new Thickness(5, 0, 0, 0);
				newBullet.Children.Add(bulletRect);
				newBullet.Children.Add(bulletText);
				bulletText.ContentStart.InsertText(relnString);	// <--- actual string passed here
				infoCanvRelationPanel.Children.Add(newBullet);
			}

		}




		private void button_addInterest(object sender, RoutedEventArgs args)
		{
			// Raise an event to add the interest.
			// The caller will in turn call "addInterest" if this is successful.
			AddInterestRequest(newInterest.Text);
			
			newInterest.SelectAll();
			newInterest.Focus();
		}

        private void button_addCourse(object sender, RoutedEventArgs args)
        {
            // Raise an event to add the course.
            // The caller will in turn call "addCourse" if this is successful.
            AddCourseRequest(newCourse.Text);

            newCourse.SelectAll();
            newCourse.Focus();
        }

        public void removeInterest(string interestName)
		{

			TextPointer findInterest = new TextPointer(TextFlow_Interests.ContentStart);

			while (((Label)findInterest.GetEmbeddedElement(LogicalDirection.Forward)).Content != interestName)
			{
				findInterest.MoveToNextContextPosition(LogicalDirection.Forward);
			}


			TextPointer limit = new TextPointer(findInterest); limit.MoveToNextContextPosition(LogicalDirection.Forward);
			findInterest.DeleteContentToPosition(limit);


		}

        public void removeCourse(string courseName)
        {

            TextPointer findCourse = new TextPointer(TextFlow_Courses.ContentStart);

            while (((Label)findCourse.GetEmbeddedElement(LogicalDirection.Forward)).Content != courseName)
            {
                findCourse.MoveToNextContextPosition(LogicalDirection.Forward);
            }


            TextPointer limit = new TextPointer(findCourse); limit.MoveToNextContextPosition(LogicalDirection.Forward);
            findCourse.DeleteContentToPosition(limit);


        }

        void InterestRemove_Click(object sender, RoutedEventArgs e)
		{
			// cast the menuitem's tag to a string, which should contain the interest name
			RemoveInterestRequest((string)((MenuItem)sender).Tag);
		}

        void CourseRemove_Click(object sender, RoutedEventArgs e)
        {
            // cast the menuitem's tag to a string, which should contain the interest name
            RemoveCourseRequest((string)((MenuItem)sender).Tag);
        }

        void gridClicked(object sender, RoutedEventArgs e)
        {
            userInfoCanv.Visibility = Visibility.Hidden;
        }

        private void ProfileClicked(object sender, RoutedEventArgs e)
		{
			if (profileExpanded)
			{
				this.FindStoryboardClock(ExpandGrid).ClockController.Deactivate();
				this.FindStoryboardClock(CollapseGrid).ClockController.Begin();
			}
			else
			{
				this.FindStoryboardClock(CollapseGrid).ClockController.Deactivate();
				this.FindStoryboardClock(ExpandGrid).ClockController.Begin();
			}

			profileExpanded = !profileExpanded;
		}


		void locKey_locKey_Hover_Event(int loc_id, Color loc_color, string loc_name)
		{
			//locPanel.viewLoc(loc_id, loc_color, loc_name);
		}

		void Friend_LeftClick_Event(string friendName)
		{
			TabItem_Messages.Focus();
			Send_Message_To.Text = friendName;
			Send_Message_Text.SelectAll();
			Send_Message_Text.Focus();
		}

        void refreshTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            // 5:40 AM.  Holy fucking shit.  I figured out the dispatcher.
            // JRP.

            if (!Dispatcher.CheckAccess())
            {
                Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal, new DispatchDelegate(UIOperation));
                return;
            }
        }
        void UIOperation()
        {
            try { RefreshClicked(null, null); }
            catch { }
        }

        void zoomEnded(object sender, EventArgs e)
        {
            this.refreshTimer.Enabled = true;
        }

        void ZoomClicked(object sender, RoutedEventArgs e)
        {
            //this.zoomTransform.ScaleX = 2;
            //this.zoomTransform.ScaleY = 2;
           
            this.FindStoryboardClock(ZoomIn).ClockController.Begin();
            this.refreshTimer.Enabled = false;

        }

//        private void ClassesClicked(object sender, RoutedEventArgs e) {
//            if (this.ClassPanel.Visibility == Visibility.Collapsed) this.ClassPanel.Visibility = Visibility.Visible;
//            else this.ClassPanel.Visibility = Visibility.Collapsed;
//        }
        private void Login(object sender, RoutedEventArgs e){
            // Raise the LoginClicked event with the entered user&pass
            LoginClicked(txtUsername.Text, txtPassword.Text);
        }
        private void Register(object sender, RoutedEventArgs e){
            //Raise the RegClicked event with the entered username, and password
            if (this.Reg_Pswd.Text == this.Reg_ConfirmPswd.Text) { }
            else
            {
                this.Reg_Pswd.Clear();
                this.Reg_ConfirmPswd.Clear();
                this.Reg_ConfirmPswd.Text = "";
            }
        }
        private void SearchNearby(object sender, RoutedEventArgs e){
            gpsSearchNearby(newLocX.Text, newLocY.Text);
        }
        public void showError(string Message){ErrorMessage.TextContent = Message;}
        private void SetLoc(object sender, RoutedEventArgs e){
        }
        private void NewLoc(object sender, RoutedEventArgs e){
            this.SetLocation.Visibility = Visibility.Hidden;
        }
        private void setNewLocCoords(object sender, RoutedEventArgs e) { }
        private void suggestLocs(object sender, RoutedEventArgs e){}
        private void AddNode(object sender, RoutedEventArgs e) { AddNodeClicked(0, null); }
        private void RemoveNode(object sender, RoutedEventArgs e) { RemoveNodeClicked(0, null); }

		private void AddNode2(object sender, RoutedEventArgs e) { AddNodeClicked(1, null); }
		private void RemoveNode2(object sender, RoutedEventArgs e) { RemoveNodeClicked(1, null); }
		
		private void UI_login(object sender, RoutedEventArgs e) { setState(state.login); }
        private void UI_register(object sender, RoutedEventArgs e) { setState(state.register); }
        private void UI_suggestedLocs(object sender, RoutedEventArgs e) { setState(state.guess); }
        private void UI_gpsLocs(object sender, RoutedEventArgs e){ setState(state.gps); }
        private void UI_running(object sender, RoutedEventArgs e){ setState(state.running); }
        private void inputPanelOKClicked(object sender, RoutedEventArgs e){
            this.FindStoryboardClock(ShowInputPanel).ClockController.Deactivate();
            this.FindStoryboardClock(HideInputPanel).ClockController.Begin();
            this.DisableStuff.Visibility = Visibility.Hidden;
            switch(InputPanelMode)
            {
                case inputMode.addFriend:
                    AddFriendRequest(inputUserText.Text);
                    break;
                case inputMode.addCourse:
                    AddCourseRequest(inputUserText.Text);
                    break;
                case inputMode.addInterest:
                    AddInterestRequest(inputUserText.Text);
                    break;
            }
            //RemoveUserRequest(inputUserText.Text);
        }



		/// <summary>
		/// This function collapses or expands the friends panel on the RHS of the running display
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void friendTitleMouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
		{
			if (friendsExpanded)
			{
				friendsExpanded = false;
				TimelineClock myParallelTimelineClock = FindStoryboardClock(collapseFriends);
				myParallelTimelineClock.ClockController.Begin();
				myParallelTimelineClock = FindStoryboardClock(expandFriends);
				myParallelTimelineClock.ClockController.Deactivate();
			}
			else
			{
				friendsExpanded = true;
				TimelineClock myParallelTimelineClock = FindStoryboardClock(collapseFriends);
				myParallelTimelineClock.ClockController.Deactivate();
				myParallelTimelineClock = FindStoryboardClock(expandFriends);
				myParallelTimelineClock.ClockController.Begin();
			}
		}

        private void inputPanelCancelClicked(object sender, RoutedEventArgs e)
        {
            this.FindStoryboardClock(ShowInputPanel).ClockController.Deactivate();
            this.FindStoryboardClock(HideInputPanel).ClockController.Begin();
            this.DisableStuff.Visibility = Visibility.Hidden;
        }

        private void AddCourse(object sender, RoutedEventArgs e){
            InputPanelMode = inputMode.addCourse;
            this.InputPanel.Visibility = Visibility.Visible;
            this.DisableStuff.Visibility = Visibility.Visible;
            this.InputPanelText.Content = "Enter the course number and name:";
            this.inputUserText.Text = "";
            this.inputUserText.Focus();
            this.FindStoryboardClock(HideInputPanel).ClockController.Deactivate();
            this.FindStoryboardClock(ShowInputPanel).ClockController.Begin();
        }
        private void AddInterest(object sender, RoutedEventArgs e){
            InputPanelMode = inputMode.addInterest;
            this.InputPanel.Visibility = Visibility.Visible;
            this.DisableStuff.Visibility = Visibility.Visible;
            this.InputPanelText.Content = "Enter an interest:";
            this.inputUserText.Text = "";
            this.inputUserText.Focus();
            this.FindStoryboardClock(HideInputPanel).ClockController.Deactivate();
            this.FindStoryboardClock(ShowInputPanel).ClockController.Begin();
        }

		private void tabChange(object sender, SelectionChangedEventArgs args)
		{
			((TabControl)sender).Background = ((TabItem)((TabControl)sender).SelectedItem).Background;
			((TabControl)sender).BorderBrush = ((TabItem)((TabControl)sender).SelectedItem).BorderBrush;
		}
		private void changeWallCancel(object sender, RoutedEventArgs args)
		{
			((TextBox)locationPanelGrid.FindId("locationPanel_wall")).Undo();
			((Button)locationPanelGrid.FindId("button_changeWall")).Content = "Change Wall";
			((Button)locationPanelGrid.FindId("button_changeWallCancel")).Visibility = Visibility.Hidden;
			((TextBox)locationPanelGrid.FindId("locationPanel_wall")).IsEnabled = false;
		}
		private void changeWall(object sender, RoutedEventArgs args)
		{
			if ((string)((Button)sender).Content == "Change Wall")
			{
				((Button)sender).Content = "Save";
				((Button)locationPanelGrid.FindId("button_changeWallCancel")).Visibility = Visibility.Visible;
				((TextBox)locationPanelGrid.FindId("locationPanel_wall")).IsEnabled = true;
				((TextBox)locationPanelGrid.FindId("locationPanel_wall")).SelectAll();
				((TextBox)locationPanelGrid.FindId("locationPanel_wall")).Focus();
			}
			else
			{
				((Button)sender).Content = "Change Wall";
				((Button)locationPanelGrid.FindId("button_changeWallCancel")).Visibility = Visibility.Hidden;
				((TextBox)locationPanelGrid.FindId("locationPanel_wall")).IsEnabled = false;
				MessageBox.Show("Send server new wall...");
			}
		}

		private void mouseEnter(object sender, System.Windows.Input.MouseEventArgs args)
		{
			MessageBox.Show("event!");
		}

        private void Min(object sender, RoutedEventArgs e){
            this.WindowState = WindowState.Minimized;
        }

        public void setState(state newState)
        {
            switch (newState)
            {
                case state.login:
                    this.LoginCanv.Visibility = Visibility.Visible;
                    this.RegCanv.Visibility = Visibility.Hidden;
                    this.SetLocation.Visibility = Visibility.Hidden;
                    this.GPSLocation.Visibility = Visibility.Hidden;
                    this.txtUsername.Focus();
                    break;
                case state.register:
                    this.LoginCanv.Visibility = Visibility.Hidden;
                    this.RegCanv.Visibility = Visibility.Visible;
                    this.SetLocation.Visibility = Visibility.Hidden;
                    this.GPSLocation.Visibility = Visibility.Hidden;
                    this.Reg_txtUsername.Focus();
                    break;
                case state.guess:
                    this.LoginCanv.Visibility = Visibility.Hidden;
                    this.RegCanv.Visibility = Visibility.Hidden;
                    this.SetLocation.Visibility = Visibility.Visible;
                    this.GPSLocation.Visibility = Visibility.Hidden;
                    break;
                case state.gps:
                    this.LoginCanv.Visibility = Visibility.Hidden;
                    this.RegCanv.Visibility = Visibility.Hidden;
                    this.SetLocation.Visibility = Visibility.Hidden;
                    this.GPSLocation.Visibility = Visibility.Visible;
                    break;
                case state.running:
                    // stuff will occur below
                    break;
            }

            if (newState == state.running)
            {
                //this.FriendsTitle.Visibility = Visibility.Visible;
                //this.FriendStackPanel.Visibility = Visibility.Visible;
//                this.ClassStackPanel.Visibility = Visibility.Visible;
                this.vizCanvas.Visibility = Visibility.Visible;
                this.keyRectangle.Visibility = Visibility.Visible;
                this.friendsRectangle.Visibility = Visibility.Visible;
                this.friendGrid.Visibility = Visibility.Visible;
                this.border1.Visibility = Visibility.Visible;
                this.Panel.Visibility = Visibility.Visible;
                this.border2.Visibility = Visibility.Visible;
//                this.MatesBlack.Visibility = Visibility.Visible;
//                this.MatesSilver.Visibility = Visibility.Hidden;
                //this.shadedRect.Visibility = Visibility.Visible;
                this.LoginCanv.Visibility = Visibility.Hidden;
                this.RegCanv.Visibility = Visibility.Hidden;
                this.SetLocation.Visibility = Visibility.Hidden;
                this.GPSLocation.Visibility = Visibility.Hidden;
                //this.zoomButton.Visibility = Visibility.Visible;
            }
            else
            {
//                this.FriendsTitle.Visibility = Visibility.Hidden;
//                this.FriendStackPanel.Visibility = Visibility.Hidden;
//                this.ClassStackPanel.Visibility = Visibility.Hidden;
                this.vizCanvas.Visibility = Visibility.Hidden;
//                this.userInfoCanv.Visibility = Visibility.Visible;
                this.keyRectangle.Visibility = Visibility.Hidden;
                this.friendsRectangle.Visibility = Visibility.Hidden;
                this.friendGrid.Visibility = Visibility.Hidden;
                this.border1.Visibility = Visibility.Hidden;
                this.Panel.Visibility = Visibility.Hidden;
                this.border2.Visibility = Visibility.Hidden;
                this.zoomButton.Visibility = Visibility.Hidden;
                //this.mainvizGrid.Visibility = Visibility.Hidden;
//                this.MatesBlack.Visibility = Visibility.Hidden;
//                this.MatesSilver.Visibility = Visibility.Visible;
                //this.shadedRect.Visibility = Visibility.Hidden;

//                this.WallButton.Visibility = Visibility.Hidden;
            }

        }
        
        //private void minimize(object sender, RoutedEventArgs e)
        //{
        //    mates_viz.Window1.WindowState = WindowState.Minimized;
        //}
        
    }


}


//eof